let Vue;

class MiniRouter {
    /**
     * 用户初始化 router 的 options 可选项
     * @param {*} options
     */
    constructor(options) {
        this.$options = options;
        this.$routeMap = {};
        this.app = new Vue({
            data() {
                return {
                    current: '',
                };
            },
        });
    }

    /**
     * 1. 监听 hash 改变事件
     * 2. 构建一个简直对的路由表，以 path 为 key，以路由配置为 value
     * 3. 注册两个全局组件：router-link router-view
     */
    init() {
        this.bindEvents();
        this.initRouteMap(this.$options.routes);
        this.initGlobalComponent();
    }

    /**
     * 监听事件
     */
    bindEvents() {
        window.addEventListener(
            'load',
            this.handleHistoryChange.bind(this),
            false
        );

        window.addEventListener(
            'hashchange',
            this.handleHistoryChange.bind(this),
            false
        );
    }

    /**
     * 监听地址栏地址改变事件
     */
    handleHistoryChange() {
        this.app.current = window.location.hash.slice(1) || '';
    }

    /**
     * 初始化 KV 路由表
     * @param {} routes
     */
    initRouteMap(routes) {
        routes.forEach((item) => {
            this.$routeMap[item.path] = item;
        });
    }

    /**
     * 注册两个全局组件
     * <router-link to="/home">首页</router-link>
     * <router-view />
     */
    initGlobalComponent() {
        // 注册 router-link
        Vue.component('router-link', {
            props: ['to'],
            // 创建 VNode
            render(h) {
                return h(
                    'a',
                    {
                        attrs: {
                            href: '#' + this.to,
                        },
                    },
                    this.$slots.default
                );
            },
        });

        // 注册 router-view
        Vue.component('router-view', {
            render: (h) => {
                const route = this.$routeMap[this.app.current];
                if (route) {
                    return h(route.component);
                }
            },
        });
    }
}

MiniRouter.install = function(_Vue) {
    Vue = _Vue;

    // 全局混入，拿到 router 实例
    Vue.mixin({
        beforeCreate() {
            if (this.$options.router) {
                Vue.prototype.$router = this.$options.router;
                // 在真正传入 router 实例时，再进行初始化，否则路由表拿不到
                this.$options.router.init();
            }
        },
    });
};

export default MiniRouter;
